package sys

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 用户相关接口
*******************************************************************************/
import (
	"permissions/api/cache"
	"permissions/model"

	"gitee.com/cloudapex/permit"
	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/gin-gonic/gin"
)

/*
 * 描述: 用户列表
 * 路由: /user/list
 * 方法: GET
 *********************************************************************/
type UserList struct {
	model.SortFinder
	model.PageFinder
	Group  int64  `form:"groupid" binding:"omitempty"`        // 用户组Id
	Name   string `form:"name" binding:"omitempty,max=64"`    // 名称
	Sex    int32  `form:"sex" binding:"omitempty"`            // 性别(1:男; 2:女)
	Phone  int64  `form:"phone" binding:"omitempty"`          // 手机
	Email  string `form:"email" binding:"omitempty"`          // 邮箱
	State  int    `form:"state" binding:"omitempty"`          // 状态(1:正常;2:失效)
	Remark string `form:"remark" binding:"omitempty,max=128"` // 备注
}

func (this *UserList) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	m := &model.User{
		Name:   this.Name,
		Sex:    this.Sex,
		Phone:  this.Phone,
		Email:  this.Email,
		State:  this.State,
		Remark: this.Remark,
	}

	total, items, err := 0, []model.User{}, error(nil)

	util.Cast(this.Group == 0,
		func() { total, items, err = this.handUser(c, m) },  // 不含用户组查找
		func() { total, items, err = this.handGroup(c, m) }) // 含有用户组查找

	if err != nil {
		return htp.RespDBErr("", err)
	}

	return htp.RespOK("", &struct {
		Total int          `json:"total"`
		List  []model.User `json:"list"`
	}{total, items})
}
func (this *UserList) handUser(c *gin.Context, m *model.User) (total int, items []model.User, err error) {
	m.Sorte, m.Pager = this.SortFinder, this.PageFinder
	return m.Find(permit.CurrDataScope(c))
}
func (this *UserList) handGroup(c *gin.Context, m *model.User) (total int, items []model.User, err error) {
	return (&model.UserWithUserGroup{
		User:      *m,
		UserGroup: model.UserGroup{GroupId: this.Group},
		Sorte:     this.SortFinder,
		Pager:     this.PageFinder,
	}).FindUsers(permit.CurrDataScope(c))
}

/*
 * 描述: 新增用户
 * 路由: /user/add
 * 方法: POST
 *********************************************************************/
type UserAdd struct {
	Id     int64  `form:"uid" binding:"required"`                           // 用户Id
	Name   string `form:"name" json:"name" binding:"required,max=64"`       // 名称
	Sex    int32  `form:"sex" json:"sex" binding:"required"`                // 性别(1:男; 2:女)
	Phone  int64  `form:"phone" json:"phone" binding:"required"`            // 手机
	Email  string `form:"email" json:"email" binding:"omitempty"`           // 邮箱
	State  int    `form:"state" json:"state" binding:"required"`            // 状态(1:正常;2:失效)
	Remark string `form:"remark" json:"remark" binding:"omitempty,max=128"` // 备注
}

func (this *UserAdd) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	m := model.User{
		Id:     this.Id,
		Name:   this.Name,
		Sex:    this.Sex,
		Phone:  this.Phone,
		Email:  this.Email,
		State:  this.State,
		Remark: this.Remark,
	}
	if _, err := m.Create(); err != nil {
		return htp.RespDBErr("", err)
	}
	return htp.RespOK("", nil)
}

/*
 * 描述: 编辑用户
 * 路由: /user/upd
 * 方法: POST
 *********************************************************************/
type UserUpd struct {
	Id     int64  `form:"id" json:"id" binding:"required"`                  // 用户Id
	Name   string `form:"name" json:"name" binding:"required,max=64"`       // 名称
	Sex    int32  `form:"sex" json:"sex" binding:"required"`                // 性别(1:男; 2:女)
	Phone  int64  `form:"phone" json:"phone" binding:"required"`            // 手机
	Email  string `form:"email" json:"email" binding:"omitempty"`           // 邮箱
	State  int    `form:"state" json:"state" binding:"required"`            // 状态(1:正常;2:失效)
	Remark string `form:"remark" json:"remark" binding:"omitempty,max=128"` // 备注
}

func (this *UserUpd) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	m := model.User{
		Id:     this.Id,
		Name:   this.Name,
		Sex:    this.Sex,
		Phone:  this.Phone,
		Email:  this.Email,
		State:  this.State,
		Remark: this.Remark,
	}
	// 更新记录, 允许后面的几个字段被重置为默认值
	if _, err := m.Update(this.Id, "phone", "email", "remark"); err != nil {
		return htp.RespDBErr("", err)
	}

	if m.State == model.EState_Unable {
		util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
			if err := cache.HandUserRoles([]int64{this.Id}, false, true); err != nil {
				util.Error("UserSta.HandUserRoles err:%v", err)
			}
		})
	}
	return htp.RespOK("", nil)
}

/*
 * 描述: 更改用户状态
 * 路由: /user/sta
 * 方法: POST
 *********************************************************************/
type UserSta struct {
	Id    int64 `form:"id" json:"id" binding:"required"`       // 用户Id
	State int   `form:"state" json:"state" binding:"required"` // 状态(1:正常;2:失效)
}

func (this *UserSta) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)
	m := model.User{State: this.State}
	if _, err := m.Update(this.Id); err != nil {
		return htp.RespDBErr("", err)
	}
	if m.State == model.EState_Unable {
		util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
			if err := cache.HandUserRoles([]int64{this.Id}, false, true); err != nil {
				util.Error("UserSta.HandUserRoles err:%v", err)
			}
		})
	}
	return htp.RespOK("", nil)
}

/*
 * 描述: 删除用户
 * 路由: /user/del
 * 方法: POST
 *********************************************************************/

type UserDel struct {
	Id int64 `form:"id" json:"id" binding:"required"` // 用户Id
}

func (this *UserDel) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	eff, err := (&model.User{}).Delete(this.Id)
	if err != nil {
		return htp.RespDBErr("", err)
	}
	if eff == 0 {
		return htp.RespErr(htp.CodeTargetNotFound, "此用户不存在", nil)
	}

	// util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
	// 	if err := HandUserRoles(this.Id, true); err != nil {
	// 		util.Error("UserDel.HandUserRoles err:%v", err)
	// 	}
	// })
	return htp.RespOK("", nil)
}

/*
 * 描述: 获取用户的组织角色
 * 路由: /user/choice
 * 方法: GET
 *********************************************************************/
type UserChoice struct {
	Id int64 `form:"id" binding:"required"` // 用户Id
}

func (this *UserChoice) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	// for role
	rIds, err := (&model.UserRole{UserId: this.Id}).FindIds()
	if err != nil {
		return htp.RespDBErr("", err)
	}

	// for group
	gIds, err := (&model.UserGroup{UserId: this.Id}).FindIds()
	if err != nil {
		return htp.RespDBErr("", err)
	}

	return htp.RespOK("", &struct {
		RIds []int64 `json:"rids"` // 角色Ids
		GIds []int64 `json:"gids"` // 用户组Ids
	}{rIds, gIds})
}

/*
 * 描述: 修改用户的组织角色
 * 路由: /user/choose
 * 方法: POST
 *********************************************************************/
type UserChoose struct {
	Id   int64   `form:"uid" json:"uid" binding:"required"`    // 用户Id
	RIds []int64 `form:"rids" json:"rids" binding:"omitempty"` // 角色Ids
	GIds []int64 `form:"gids" json:"gids" binding:"omitempty"` // 用户组Ids
}

func (this *UserChoose) Handle(c *gin.Context) htp.Response {
	if has, err := (&model.User{Id: this.Id}).Load(); !has || err != nil {
		return htp.RespDBErr("此角色不存在", err)
	}
	if vry, err := (&model.Role{}).VerifyIds(this.RIds); !vry || err != nil {
		return htp.RespDBErr("角色验证失败", err)
	}
	if vry, err := (&model.Group{}).VerifyIds(this.GIds); !vry || err != nil {
		return htp.RespDBErr("用户组验证失败", err)
	}

	// 更新用户与角色的关联
	mr := model.UserRole{}
	if _, err := mr.Delete(this.Id, 0); err != nil {
		return htp.RespDBErr("用户角色操作失败", err)
	}
	if err := mr.Insert(this.Id, this.RIds); err != nil {
		return htp.RespDBErr("用户角色更新失败", err)
	}

	// 更新用户与用户组的关联
	mg := model.UserGroup{}
	if _, err := mg.Delete(this.Id, 0); err != nil {
		return htp.RespDBErr("用户组操作失败", err)
	}
	if err := mg.Insert(this.Id, this.GIds); err != nil {
		return htp.RespDBErr("用户组更新失败", err)
	}

	util.Goroutine("HandUserRoles", func() { // 更新用户角色缓存
		if err := cache.HandUserRoles([]int64{this.Id}, false); err != nil {
			util.Error("UserChoose.HandUserRoles err:%v", err)
		}
	})
	return htp.RespOK("", nil)
}

/*
 * 描述: 获取用户的权限信息
 * 路由: /user/permis
 * 方法: GET
 *********************************************************************/
type UserPermis struct {
	UId   int64  `form:"uid" binding:"omitempty"`         // UId
	Name  string `form:"name" binding:"omitempty,max=64"` // 名称
	Phone int64  `form:"phone" binding:"omitempty"`       // 手机
}

func (this *UserPermis) Handle(c *gin.Context) htp.Response {
	//user := model.CurrUser(c)

	if this.UId == 0 && this.Name == "" && this.Phone == 0 {
		return htp.RespParamErr("请至少使用一个查询条件", nil)
	}

	mUsr := model.User{Id: this.UId, Name: this.Name, Phone: this.Phone}
	if has, err := mUsr.Load(); !has || err != nil {
		return htp.RespErr(htp.CodeTargetNotFound, "目标不存在", nil)
	}

	// 所属用户组
	grups, err := (&model.UserGroupWithGroup{
		model.UserGroup{UserId: mUsr.Id},
		model.Group{Tntyp: model.ETreeNode_Leaf},
	}).FindChains()
	if err != nil {
		return htp.RespDBErr("", err)
	}

	// 拥有的角色
	aIds, err := (&model.UserRole{UserId: mUsr.Id}).FindIds()
	if err != nil {
		return htp.RespDBErr("", err)
	}
	rIds, err := (&model.UserGroupWithGroupRole{UserGroup: model.UserGroup{UserId: mUsr.Id}}).FindRoleIds()
	if err != nil {
		return htp.RespDBErr("", err)
	}
	aIds = util.RemoveDuplicate64(append(aIds, rIds...))
	roles, err := (&model.Role{CInIds: aIds}).FindLabs()

	// 拥有的权限
	powers, err := (&model.RolePowerWithPower{RolePower: model.RolePower{CInRIds: aIds}}).FindChains(model.EPower_Func, model.EPower_Data)
	if err != nil {
		return htp.RespDBErr("", err)
	}
	return htp.RespOK("", &struct {
		Groups []model.GroupChain `json:"groups"`
		Roles  []model.RoleLable  `json:"roles"`
		Powers []model.PowerChain `json:"powers"`
	}{grups, roles, powers})
}
